﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Windows;
using PairingMatrix.Common.Command;
using PairingMatrix.Common.Enum;
using PairingMatrix.Model;
using System.Linq;
using PairingMatrix.View;

namespace PairingMatrix.ViewModel
{
    public class TeamMemberCardViewModel : ViewModelBase, ITeamMemberCardViewModel
    {
        private readonly TeamMemberModel _model;
        private static int _staticOrderOfThisCard = 0;
        public ObservableCollection<string> IceCreams { get; set;}
        
        public TeamMemberCardViewModel(TeamMemberModel model)
        {
            this._model = model;
            _model.PropertyChanged += _model_PropertyChanged;
            PairedWith = new ObservableCollection<PairedWithViewModel>();
            _model.PairedWith.CollectionChanged += PairedWith_CollectionChanged;
            
            ProjectCardAssignments = new ObservableCollection<ProjectCardAssignmentViewModel>();
            _model.ProjectCardAssignments.CollectionChanged += ProjectCardAssignments_CollectionChanged;

            ShowCardInAbsenteesBox = false;
            
            _staticOrderOfThisCard++;
            _order = _staticOrderOfThisCard;

            IceCreams = new ObservableCollection<string>();
            _model.IceCreams.ToList().ForEach(i => IceCreams.Add(i.ToString("d/M")));
            _model.IceCreams.CollectionChanged += IceCreams_CollectionChanged;
        }

        void IceCreams_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    IceCreams.Add(((DateTime)e.NewItems[0]).ToString("d/M"));
                    break;
                case NotifyCollectionChangedAction.Reset:
                    IceCreams.Clear();
                    break;
                case NotifyCollectionChangedAction.Remove:
                    IceCreams.Remove(IceCreams.First(i=> i == ((DateTime)e.OldItems[0]).ToString("d/M")));
                    break;
            }
        }

        void ProjectCardAssignments_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    ProjectCardAssignments.Add(new ProjectCardAssignmentViewModel((ProjectCardAssignmentModel)e.NewItems[0]));
                    break;
                case NotifyCollectionChangedAction.Reset:
                    ProjectCardAssignments.Clear();
                    break;
            }
        }

        void PairedWith_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    PairedWith.Add(new PairedWithViewModel((PairedWithModel)e.NewItems[0]));
                    break;
                case NotifyCollectionChangedAction.Reset:
                    PairedWith.Clear();
                    break;
            }
        }

        void _model_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (IsValidProperty(e.PropertyName))
                OnPropertyChanged(e.PropertyName);
        }

        public Guid Id
        {
            get { return _model.Id; }
        }

        public string Name
        {
            get { return _model.Name; }
            set 
            {
                if (_model.Name == value)
                    return;
                _model.Name = value;
                OnPropertyChanged("Name");
            }
        }

        public Point Position
        {
            get { return _model.Position; }
            set
            {
                if (_model.Position == value)
                    return;
                _model.Position = value;
                OnPropertyChanged("Position");
            }
        }

        private int _order;
        public int Order
        {
            get { return _order; }
            set
            {
                if (_order == value)
                    return;
                _order = value;
                OnPropertyChanged("Order");
            }
        }

        public TeamMemberModel Model
        {
            get { return _model; }
        }


        public ObservableCollection<PairedWithViewModel> PairedWith { get; set;}
        public ObservableCollection<ProjectCardAssignmentViewModel> ProjectCardAssignments { get; set; }

        public string PhotoUri
        {
            get { return _model.Name.StartsWith("[Member ") ? "/PairingMatrix;component/View/Photo/Default.jpg": "/PairingMatrix;component/View/Photo/" + _model.Name + ".jpg"; }
            set 
            {
                if (_model.PhotoUri == value)
                    return;
                _model.PhotoUri = value;
                OnPropertyChanged("PhotoUri");
            }
        }


        private RelayCommand _toggleEditModeCommand;
        public RelayCommand ToggleEditModeCommand
        {
            get
            {
                return _toggleEditModeCommand ??
                       (_toggleEditModeCommand = new RelayCommand(param =>
                                                                  {
                                                                      if (IsInEditMode)
                                                                          _model.Save();
                                                                      IsInEditMode = !IsInEditMode;
                                                                  }));
            }
        }

        private bool _isInEditMode;
        public bool IsInEditMode
        {
            get { return _isInEditMode; }
            set
            {
                if (_isInEditMode == value)
                    return;
                _isInEditMode = value;
                OnPropertyChanged("IsInEditMode");
            }
        }

        private bool arrangeCardToShowStatistics;
        public bool ArrangeCardToShowStatistics
        {
            get { return arrangeCardToShowStatistics; }
            set
            {
                if (arrangeCardToShowStatistics == value)
                    return;
                arrangeCardToShowStatistics = value;
                OnPropertyChanged("ArrangeCardToShowStatistics");
            }
        }

        private bool _arrangeCardToShowIceCreamMeter;
        public bool ArrangeCardToShowIceCreamMeter
        {
            get { return _arrangeCardToShowIceCreamMeter; }
            set
            {
                if (_arrangeCardToShowIceCreamMeter == value)
                    return;
                _arrangeCardToShowIceCreamMeter = value;
                OnPropertyChanged("ArrangeCardToShowIceCreamMeter");
            }
        }

        private bool _showStatistics; 
        public bool ShowStatistics 
        {
            get { return _showStatistics; }
            set
            {
                if (_showStatistics == value)
                    return;
                _showStatistics = value;
                OnPropertyChanged("ShowStatistics");
            }
        }


        public bool ShowCardInAbsenteesBox
        {
            get { return _model.ShowCardInAbsenteesBox; }
            set
            {
                if (_model.ShowCardInAbsenteesBox == value)
                    return;
                _model.ShowCardInAbsenteesBox = value;
                OnPropertyChanged("ShowCardInAbsenteesBox");
            }
        }


        public WallType Wall
        {
            get { return _model.Wall; }
        }

        public int NumberOfSignUpsWithSelectedTeamMember
        {
            get { return _model.NumberOfSignUpsWithSelectedTeamMember; }
        }

        public PairingLevel PairingLevelWithSelectedTeamMember
        {
            get { return _model.PairingLevelWithSelectedTeamMember; }
        }

        private bool _showNumberOfDaysPairedWithSelectedTeamMember;
        public bool ShowNumberOfDaysPairedWithSelectedTeamMember
        {
            get { return _showNumberOfDaysPairedWithSelectedTeamMember; }
            set
            {
                if (_showNumberOfDaysPairedWithSelectedTeamMember == value)
                    return;
                _showNumberOfDaysPairedWithSelectedTeamMember = value;
                OnPropertyChanged("NumberOfSignUpsWithSelectedTeamMember");
                OnPropertyChanged("PairingLevelWithSelectedTeamMember");
                OnPropertyChanged("ShowNumberOfDaysPairedWithSelectedTeamMember");
            }
        }


        public bool HasSignUpsOnCurrentWall
        {
            get { return _model.HasSignUpsOnCurrentWall; }
        }

        private RelayCommand _deleteCommand;
        public RelayCommand DeleteCommand
        {
            get
            {
                return _deleteCommand ??
                       (_deleteCommand = new RelayCommand(param => ((ICardWallViewModel)
                                                                            ControlRegistry.CardWallControl.DataContext).DeleteTeamMemberCard(Id)));
            }
        }

        public void AddIceCream(DateTime date)
        {
            _model.AddIceCream(date);
        }

        private int _iceCreamCost; 
        public int IceCreamCost 
        {
            get { return _iceCreamCost; }
            set
            {
                if (_iceCreamCost == value)
                    return;
                _iceCreamCost = value;
                OnPropertyChanged("IceCreamCost");
            }
        }

        public void CalculateIceCreamCost(double totalCostOfIceCreams, double totalCountOfIceCreams)
        {
            IceCreamCost = (int) ((int) totalCountOfIceCreams == 0 ? 0 : totalCostOfIceCreams / totalCountOfIceCreams * IceCreams.Count);
        }

        public void ClearIceCreams()
        {
            Model.ClearIceCreams();
        }
    }
}
